import { ref } from "vue";
import { Graph, Shape } from "@antv/x6";
import centerIcon from "@/assets/images/centerIcon.png";
import { History } from "@antv/x6-plugin-history";
import { Selection } from "@antv/x6-plugin-selection";
import { Snapline } from "@antv/x6-plugin-snapline";
import { Keyboard } from "@antv/x6-plugin-keyboard";
import { stopDrawEdgeAndNode } from "@/utils/antvx6/nodeOrEdge";
import { getNodeOrEdgeDel } from "@/utils/antvx6/nodeOrEdgeDel";
import { connectedEdge } from "@/utils/antvx6/edge";
import { insertNode } from "@/utils/antvx6/InsertNode";
import { addNodeTranslation } from "@/utils/antvx6/nodeTranslation";
import { addMovedNode } from "@/utils/antvx6/movedNode";
import { useToolStore } from "@/store/modules/tools";
import { useStorage } from "@vueuse/core";
import { renderData } from "@/utils/antvx6/renderCanvas";
import { registerNode } from "@/utils/antvx6/registerShapeComponents";
import { getNodesDetail, getEdgesDetail, getAreaDetail } from "@/utils/antvx6/nodeAndEdgeDetail";
import { changeNodePointAngle } from "@/utils/antvx6/changeNodePointAngle";
const toolStore = useToolStore();
// 画布元素
let container: HTMLElement | undefined;
let openRefs: HTMLElement | undefined; // 节点、边弹窗ref
let openAreaRefs: HTMLElement | undefined;
export const domContainer = (HTMLElements: any, openRef: any, openAreaRef: any) => {
  container = HTMLElements;
  openRefs = openRef;
  openAreaRefs = openAreaRef;
  nextTick(() => {
    registerNode(() => {
      getImageSize();
    });
  });
};
const underlayUrl = ref<string>("https://t7.baidu.com/it/u=3860161733,2997250833&fm=193&f=GIF");
// 获取图片大小
const getImageSize = () => {
  const img = new Image();
  img.src = underlayUrl.value;
  img.onload = () => {
    widthGraph.value = Number(img.width);
    heightGraph.value = Number(img.height);
    getGraphs();
  };
  img.onerror = () => {
    widthGraph.value = 2000;
    heightGraph.value = 2000;
    getGraphs();
  };
};
// 画布大小
export const widthGraph = ref<number>(2000);
export const heightGraph = ref<number>(2000);
// 区分是否可编辑
const disabledInteracting = ref<boolean>(false);
export const lineMode = ref<number>(1); // 连线类型 单双行线
// 创建画布
export const graph = ref<any>();
export const getGraphs = () => {
  graph.value = new Graph({
    container: container,
    autoResize: true,
    scaling: {
      min: 0.5,
      max: 20,
    },
    translating: {
      // 限制节点的移动范围。
      restrict: {
        x: 0,
        y: 0,
        width: widthGraph.value,
        height: heightGraph.value,
      },
    },
    interacting: function (cellView) {
      if (cellView.cell.getData()?.disableMove === 1 || disabledInteracting.value) {
        return { nodeMovable: false };
      }
      return true;
    },
    grid: {
      size: 10,
      visible: true,
      type: "doubleMesh",
      args: [
        {
          color: "#4F4F4F",
          thickness: 1,
        },
        {
          color: "#484848",
          thickness: 1,
          factor: 10,
        },
      ],
    },
    panning: {
      enabled: true,
      modifiers: "shift",
      eventTypes: ["leftMouseDown"],
    }, // 是否开启拖拽平移
    mousewheel: {
      // 鼠标滚轮缩放
      enabled: true,
      modifiers: ["ctrl"],
      guard(e: WheelEvent) {
        if (e.altKey) {
          // 当按下 ctrl 键时，忽略所有滚动事件
          return false;
        }
        return true;
      },
    },
    highlighting: {
      default: {
        name: "stroke",
        args: {
          // padding: 2,
          attrs: {
            "stroke-width": 2,
            stroke: "#d87f0c",
          },
        },
      },
    },
    connecting: {
      // 连线选项
      router: "manhattan",
      connector: {
        name: "rounded",
        args: {
          radius: 8,
        },
      },
      anchor: "center",
      allowBlank: false,
      allowLoop: false,
      allowPort() {
        return disabledInteracting.value ? false : true;
      },
      snap: {
        radius: 20,
      },
      createEdge() {
        // 创建边属性
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: "#2A82E4",
              strokeWidth: 1,
              targetMarker: {
                name: "block",
                size: 2,
              },
            },
          },
          zIndex: 0,
        });
      },
      validateConnection({ targetMagnet }) {
        return !!targetMagnet;
      },
    },
  });
  graph.value
    .use(
      new History({
        enabled: true,
        ignoreAdd: false,
        ignoreRemove: false,
        ignoreChange: true,
      })
    )
    .use(
      new Snapline({
        enabled: true,
      })
    )
    .use(
      new Selection({
        rubberband: true,
        showNodeSelectionBox: true,
        showEdgeSelectionBox: true,
        modifiers: ["ctrl"],
        eventTypes: ["leftMouseDown"],
        filter: (cell) => {
          const attrs = cell.getAttrs();
          if (attrs.body?.isCanSelection === false) {
            return false;
          }
          // 过滤框选
          return !["setCenterPointStar"].includes(cell.id);
        },
      })
    )
    .use(
      new Keyboard({
        enabled: true,
        global: true,
      })
    );

  graph.value.zoom(0.5); // 画布和图形整体的缩放
  graph.value.translate(); // 图形相对画布的相对位置，平移
  setCenterPoint();
  graph.value.positionPoint({ x: 0, y: 0 }, "0%", "0%"); // 将画布的左上角与视口中的点 [0%, 0%] 对齐
  // 键盘删除结束绘制
  graph.value.bindKey("Escape", () => {
    stopDrawEdgeAndNode(graph.value);
    // 取消连接桩磁体
    const nodeList = graph.value.getNodes().filter((item: any) => item.shape === "node-point");
    nodeList.forEach((item: any) => item.prop("isShowPortMagnet", false));
    toolStore.changeTool("");
  });
  // 删除节点、边
  getNodeOrEdgeDel(graph.value);
  // 可以通过isNew来判断连线完成， 对应的边是否创建新边
  connectedEdge(graph.value, lineMode.value);
  // 边打断
  insertNode(graph.value);
  // 键盘上下左右平移移动节点
  addNodeTranslation(graph.value, widthGraph.value, heightGraph.value);
  // 节点移动后
  addMovedNode(graph.value, widthGraph.value, heightGraph.value);
  // 快捷编辑节点角度
  changeNodePointAngle(graph.value);
  graph.value.on("resize", () => {
    const option = {
      image: underlayUrl.value,
      background: "#484848",
      position: {
        x: 0,
        y: 0,
        width: widthGraph.value,
        height: heightGraph.value,
      },
    };
    graph.value?.drawBackground(option);
  });
  // 渲染画布
  handleRender();
  // 鼠标node节点双击--进行查看
  graph.value.on("node:dblclick", ({ node }) => {
    if( node.shape === 'node-point') {
      getNodesDetail(graph.value, node, openRefs);
    } else if(node.shape === 'node-area') {
      getAreaDetail(graph.value, node, openAreaRefs);
    }
  });
  // 鼠标边单击--进行查看
  graph.value.on("edge:dblclick", ({ edge }) => {
    getEdgesDetail(graph.value, edge, openRefs);
  });
  // 提供了AntV x6 Dev Tool 对页面元素进行审查的插件来帮助开发者更方便的开发应用。
  (window as any).__x6_instances__ = [];
  (window as any).__x6_instances__.push(graph.value);
};
// 设置画布中心位置
const setCenterPoint = () => {
  const model = new Shape.Image({
    id: "setCenterPointStar",
    x: 0,
    y: 0,
    width: 10,
    height: 10,
    imageUrl: centerIcon,
    data: {
      disableMove: 1, // 2为可拖拽，1不可拖拽
    },
  });
  graph.value.addNode(model);
};

// 渲染画布
const handleRender = () => {
  const data: any = useStorage("extractGraphObj", null);
  const renderObj = JSON.parse(data.value);
  if (graph.value) {
    renderData(graph.value, renderObj);
  }
};

// 卸载画布
export const uninstall = () => {
  if (graph.value) {
    graph.value.dispose();
    graph.value = null;
  }
};
